package com.google.gwt.mobile.phonegap.api;

import java.util.Date;

import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.core.client.JsArray;
import com.google.gwt.core.client.JsArrayString;

/**
 * The Class Contacts.
 */
public class Contacts {

  /**
   * New instance.
   * 
   * @return the contact
   */
  public static final native Contact newInstance() /*-{
		return new $wnd.navigator.service.contacts.create();
  }-*/;

  /**
   * Find.
   * 
   * @param fields the fields
   * @param callback the callback
   * @param options the options
   */
  public static final void find(final ContactFields fields, final ContactFindCallback callback,
      final ContactFindOptions options) {
    find(fields.getFields(), callback, options.getOptions());
  }

  private static final native void find(JsArrayString fields, ContactFindCallback callback,
      JavaScriptObject options) /*-{
		$wnd.navigator.service.contacts
				.find(
						fields,
						function(contacts) {
							callback.@com.google.gwt.mobile.phonegap.api.Contacts.ContactFindCallback::onSuccess(Lcom/google/gwt/core/client/JsArray;)(contacts);
						},
						function(error) {
							callback.@com.google.gwt.mobile.phonegap.api.Contacts.ContactFindCallback::onError(Lcom/google/gwt/mobile/phonegap/api/Contacts$ContactError;)(error);
						}, options);
  }-*/;

  /**
   * The Class Contact.
   */
  public static class Contact extends JavaScriptObject {

    protected Contact() {
    }

    /**
     * Save.
     * 
     * @param callback the callback
     */
    public final native void save(Callback callback) /*-{
			this
					.save(
							function() {
								callback.@com.google.gwt.mobile.phonegap.api.Contacts.Callback::onSuccess()();
							},
							function(error) {
								callback.@com.google.gwt.mobile.phonegap.api.Contacts.Callback::onError(Lcom/google/gwt/mobile/phonegap/api/Contacts$ContactError;)(error);
							});
    }-*/;

    /*
     * (non-Javadoc)
     * 
     * @see java.lang.Object#clone()
     */
    public final native Contact clone() /*-{
			return this.clone();
    }-*/;

    /**
     * Removes the.
     * 
     * @param callback the callback
     */
    public final native void remove(Callback callback) /*-{
			this
					.remove(
							function() {
								callback.@com.google.gwt.mobile.phonegap.api.Contacts.Callback::onSuccess()();
							},
							function(error) {
								callback.@com.google.gwt.mobile.phonegap.api.Contacts.Callback::onError(Lcom/google/gwt/mobile/phonegap/api/Contacts$ContactError;)(error);
							});
    }-*/;

    /**
     * Gets the id.
     * 
     * @return the id
     */
    public final native String getId() /*-{
			return this.id;
    }-*/;

    /**
     * Sets the id.
     * 
     * @param id the new id
     */
    public final native void setId(String id) /*-{
			this.id = id;
    }-*/;

    /**
     * Gets the display name.
     * 
     * @return the display name
     */
    public final native String getDisplayName() /*-{
			return this.displayName;
    }-*/;

    /**
     * Sets the display name.
     * 
     * @param displayName the new display name
     */
    public final native void setDisplayName(String displayName) /*-{
			this.displayName = displayName;
    }-*/;

    /**
     * Gets the name.
     * 
     * @return the name
     */
    public final native ContactName getName() /*-{
			return this.name;
    }-*/;

    /**
     * Sets the name.
     * 
     * @param name the new name
     */
    public final native void setName(ContactName name) /*-{
			this.name = name;
    }-*/;

    /**
     * Gets the nickname.
     * 
     * @return the nickname
     */
    public final native String getNickname() /*-{
			return this.nickname;
    }-*/;

    /**
     * Sets the nickname.
     * 
     * @param nickname the new nickname
     */
    public final native void setNickname(String nickname) /*-{
			this.nickname = nickname;
    }-*/;

    /**
     * Gets the phone numbers.
     * 
     * @return the phone numbers
     */
    public final native JsArray<ContactField> getPhoneNumbers() /*-{
			return this.phoneNumbers;
    }-*/;

    /**
     * Gets the phone numbers.
     * 
     * @param phoneNumbers the phone numbers
     * @return the phone numbers
     */
    public final native void getPhoneNumbers(JsArray<ContactField> phoneNumbers) /*-{
			this.phoneNumbers = phoneNumbers;
    }-*/;

    /**
     * Gets the emails.
     * 
     * @return the emails
     */
    public final native JsArray<ContactField> getEmails() /*-{
			return this.emails;
    }-*/;

    /**
     * Sets the emails.
     * 
     * @param emails the new emails
     */
    public final native void setEmails(JsArray<ContactField> emails) /*-{
			this.emails = emails;
    }-*/;

    /**
     * Gets the addresses.
     * 
     * @return the addresses
     */
    public final native JsArray<ContactAddress> getAddresses() /*-{
			return this.addresses;
    }-*/;

    /**
     * Sets the addresses.
     * 
     * @param addresses the new addresses
     */
    public final native void setAddresses(JsArray<ContactAddress> addresses) /*-{
			this.addresses = addresses;
    }-*/;

    /**
     * Gets the i ms.
     * 
     * @return the i ms
     */
    public final native JsArray<ContactField> getIMs() /*-{
			return this.ims;
    }-*/;

    /**
     * Sets the i ms.
     * 
     * @param ims the new i ms
     */
    public final native void setIMs(JsArray<ContactField> ims) /*-{
			this.ims = ims;
    }-*/;

    /**
     * Gets the organizations.
     * 
     * @return the organizations
     */
    public final native JsArray<ContactOrganization> getOrganizations() /*-{
			return this.organizations;
    }-*/;

    /**
     * Gets the organizations.
     * 
     * @param organizations the organizations
     * @return the organizations
     */
    public final native void getOrganizations(JsArray<ContactOrganization> organizations) /*-{
			this.organizations = organizations;
    }-*/;

    /**
     * Gets the published.
     * 
     * @return the published
     */
    public final native String getPublished() /*-{
			return this.published;
    }-*/;

    /**
     * Sets the published.
     * 
     * @param published the new published
     */
    public final native void setPublished(String published) /*-{
			this.published = published;
    }-*/;

    /**
     * Gets the updated.
     * 
     * @return the updated
     */
    public final native String getUpdated() /*-{
			return this.updated;
    }-*/;

    /**
     * Sets the updated.
     * 
     * @param updated the new updated
     */
    public final native void setUpdated(String updated) /*-{
			this.updated = updated;
    }-*/;

    /**
     * Gets the birthday.
     * 
     * @return the birthday
     */
    public final native String getBirthday() /*-{
			return this.birthday;
    }-*/;

    /**
     * Sets the birthday.
     * 
     * @param birthday the new birthday
     */
    public final native void setBirthday(String birthday) /*-{
			this.birthday = birthday;
    }-*/;

    /**
     * Gets the anniversary.
     * 
     * @return the anniversary
     */
    public final native String getAnniversary() /*-{
			return this.anniversary;
    }-*/;

    /**
     * Sets the anniversary.
     * 
     * @param anniversity the new anniversary
     */
    public final native void setAnniversary(String anniversity) /*-{
			this.anniversary = anniversity;
    }-*/;

    /**
     * Gets the gender.
     * 
     * @return the gender
     */
    public final native String getGender() /*-{
			return this.gender;
    }-*/;

    /**
     * Sets the gender.
     * 
     * @param gender the new gender
     */
    public final native void setGender(String gender) /*-{
			this.gender = gender;
    }-*/;

    /**
     * Gets the note.
     * 
     * @return the note
     */
    public final native String getNote() /*-{
			return this.note;
    }-*/;

    /**
     * Sets the note.
     * 
     * @param note the new note
     */
    public final native void setNote(String note) /*-{
			this.note = note;
    }-*/;

    /**
     * Gets the preferred username.
     * 
     * @return the preferred username
     */
    public final native String getPreferredUsername() /*-{
			return this.preferredUsername;
    }-*/;

    /**
     * Sets the preferred username.
     * 
     * @param preferredUsername the new preferred username
     */
    public final native void setPreferredUsername(String preferredUsername) /*-{
			this.preferredUsername = preferredUsername;
    }-*/;

    /**
     * Gets the photos.
     * 
     * @return the photos
     */
    public final native JsArray<ContactField> getPhotos() /*-{
			return this.photos;
    }-*/;

    /**
     * Sets the photos.
     * 
     * @param photos the new photos
     */
    public final native void setPhotos(JsArray<ContactField> photos) /*-{
			this.photos = photos;
    }-*/;

    /**
     * Gets the tags.
     * 
     * @return the tags
     */
    public final native JsArray<ContactField> getTags() /*-{
			return this.tags;
    }-*/;

    /**
     * Sets the tags.
     * 
     * @param tags the new tags
     */
    public final native void setTags(JsArray<ContactField> tags) /*-{
			this.tags = tags;
    }-*/;

    /**
     * Gets the relationships.
     * 
     * @return the relationships
     */
    public final native JsArray<ContactField> getRelationships() /*-{
			return this.relationships;
    }-*/;

    /**
     * Sets the relationships.
     * 
     * @param relationships the new relationships
     */
    public final native void setRelationships(JsArray<ContactField> relationships) /*-{
			this.relationships = relationships;
    }-*/;

    /**
     * Gets the uR ls.
     * 
     * @return the uR ls
     */
    public final native JsArray<ContactField> getURLs() /*-{
			return this.urls;
    }-*/;

    /**
     * Sets the uR ls.
     * 
     * @param urls the new uR ls
     */
    public final native void setURLs(JsArray<ContactField> urls) /*-{
			this.urls = urls;
    }-*/;

    /**
     * Gets the accounts.
     * 
     * @return the accounts
     */
    public final native JsArray<ContactAccount> getAccounts() /*-{
			return this.accounts;
    }-*/;

    /**
     * Sets the accounts.
     * 
     * @param accounts the new accounts
     */
    public final native void setAccounts(JsArray<ContactAccount> accounts) /*-{
			this.accounts = accounts;
    }-*/;

    /**
     * Gets the uTC offset.
     * 
     * @return the uTC offset
     */
    public final native String getUTCOffset() /*-{
			return this.utcOffset;
    }-*/;

    /**
     * Sets the uTC offset.
     * 
     * @param utcOffset the new uTC offset
     */
    public final native void setUTCOffset(String utcOffset) /*-{
			this.utcOffset = utcOffset;
    }-*/;

    /**
     * Gets the connected.
     * 
     * @return the connected
     */
    public final native boolean getConnected() /*-{
			return this.connected;
    }-*/;

    /**
     * Sets the connected.
     * 
     * @param connected the new connected
     */
    public final native void setConnected(boolean connected) /*-{
			this.connected = connected;
    }-*/;
  }

  /**
   * The Class ContactName.
   */
  public static class ContactName extends JavaScriptObject {

    protected ContactName() {
    };

    /**
     * New instance.
     * 
     * @return the contact name
     */
    public static final ContactName newInstance() {
      return (ContactName) JavaScriptObject.createObject();
    }

    /**
     * Gets the formatted.
     * 
     * @return the formatted
     */
    public final native String getFormatted() /*-{
			return this.formatted;
    }-*/;

    /**
     * Sets the formatted.
     * 
     * @param formatted the new formatted
     */
    public final native void setFormatted(String formatted) /*-{
			this.formatted = formatted;
    }-*/;

    /**
     * Gets the family name.
     * 
     * @return the family name
     */
    public final native String getFamilyName() /*-{
			return this.familyName;
    }-*/;

    /**
     * Sets the family name.
     * 
     * @param familyName the new family name
     */
    public final native void setFamilyName(String familyName) /*-{
			this.familyName = familyName;
    }-*/;

    /**
     * Gets the given name.
     * 
     * @return the given name
     */
    public final native String getGivenName() /*-{
			return this.givenName;
    }-*/;

    /**
     * Sets the given name.
     * 
     * @param givenName the new given name
     */
    public final native void setGivenName(String givenName) /*-{
			this.givenName = givenName;
    }-*/;

    /**
     * Gets the middle name.
     * 
     * @return the middle name
     */
    public final native String getMiddleName() /*-{
			return this.middleName;
    }-*/;

    /**
     * Sets the middle name.
     * 
     * @param middleName the new middle name
     */
    public final native void setMiddleName(String middleName) /*-{
			this.middleName = middleName;
    }-*/;

    /**
     * Gets the hororific prefix.
     * 
     * @return the hororific prefix
     */
    public final native String getHororificPrefix() /*-{
			return this.hororificPrefix;
    }-*/;

    /**
     * Sets the hororific prefix.
     * 
     * @param hororificPrefix the new hororific prefix
     */
    public final native void setHororificPrefix(String hororificPrefix) /*-{
			this.hororificPrefix = hororificPrefix;
    }-*/;

    /**
     * Gets the honorific suffix.
     * 
     * @return the honorific suffix
     */
    public final native String getHonorificSuffix() /*-{
			return this.honorificSuffix;
    }-*/;

    /**
     * Sets the honorific suffix.
     * 
     * @param honorificSuffix the new honorific suffix
     */
    public final native void setHonorificSuffix(String honorificSuffix) /*-{
			this.honorificSuffix = honorificSuffix;
    }-*/;

  }

  /**
   * The Class ContactField.
   */
  public static class ContactField extends JavaScriptObject {

    protected ContactField() {
    };

    /**
     * New instance.
     * 
     * @return the contact field
     */
    public static final ContactField newInstance() {
      return (ContactField) JavaScriptObject.createObject();
    }

    /**
     * Gets the type.
     * 
     * @return the type
     */
    public final native String getType() /*-{
			return this.type;
    }-*/;

    /**
     * Sets the type.
     * 
     * @param type the new type
     */
    public final native void setType(String type) /*-{
			this.type = type;
    }-*/;

    /**
     * Gets the value.
     * 
     * @return the value
     */
    public final native String getValue() /*-{
			return this.value;
    }-*/;

    /**
     * Sets the value.
     * 
     * @param value the new value
     */
    public final native void setValue(String value) /*-{
			this.value = value;
    }-*/;

    /**
     * Gets the primary.
     * 
     * @return the primary
     */
    public final native boolean getPrimary() /*-{
			return this.primary;
    }-*/;

    /**
     * Sets the primary.
     * 
     * @param primary the new primary
     */
    public final native void setPrimary(boolean primary) /*-{
			this.primary = primary;
    }-*/;

  }

  /**
   * The Class ContactAddress.
   */
  public static class ContactAddress extends JavaScriptObject {

    protected ContactAddress() {
    };

    /**
     * New instance.
     * 
     * @return the contact address
     */
    public static final ContactAddress newInstance() {
      return (ContactAddress) JavaScriptObject.createObject();
    }

    /**
     * Gets the formatted.
     * 
     * @return the formatted
     */
    public final native String getFormatted() /*-{
			return this.formatted;
    }-*/;

    /**
     * Sets the formatted.
     * 
     * @param formatted the new formatted
     */
    public final native void setFormatted(String formatted) /*-{
			this.formatted = formatted;
    }-*/;

    /**
     * Gets the street address.
     * 
     * @return the street address
     */
    public final native String getStreetAddress() /*-{
			return this.streetAddress;
    }-*/;

    /**
     * Sets the street address.
     * 
     * @param streetAddress the new street address
     */
    public final native void setStreetAddress(String streetAddress) /*-{
			this.streetAddress = streetAddress;
    }-*/;

    /**
     * Gets the locality.
     * 
     * @return the locality
     */
    public final native String getLocality() /*-{
			return this.locality;
    }-*/;

    /**
     * Gets the locality.
     * 
     * @param locality the locality
     * @return the locality
     */
    public final native void getLocality(String locality) /*-{
			this.locality = locality;
    }-*/;

    /**
     * Gets the region.
     * 
     * @return the region
     */
    public final native String getRegion() /*-{
			return this.region;
    }-*/;

    /**
     * Sets the region.
     * 
     * @param region the new region
     */
    public final native void setRegion(String region) /*-{
			this.region = region;
    }-*/;

    /**
     * Gets the postal code.
     * 
     * @return the postal code
     */
    public final native String getPostalCode() /*-{
			return this.postalCode;
    }-*/;

    /**
     * Sets the postal code.
     * 
     * @param postalCode the new postal code
     */
    public final native void setPostalCode(String postalCode) /*-{
			this.postalCode = postalCode;
    }-*/;

    /**
     * Gets the country.
     * 
     * @return the country
     */
    public final native String getCountry() /*-{
			return this.country;
    }-*/;

    /**
     * Sets the country.
     * 
     * @param country the new country
     */
    public final native void setCountry(String country) /*-{
			this.country = country;
    }-*/;

  }

  /**
   * The Class ContactOrganization.
   */
  public static class ContactOrganization extends JavaScriptObject {

    protected ContactOrganization() {
    };

    /**
     * New instance.
     * 
     * @return the contact organization
     */
    public static final ContactOrganization newInstance() {
      return (ContactOrganization) JavaScriptObject.createObject();
    }

    /**
     * Gets the name.
     * 
     * @return the name
     */
    public final native String getName() /*-{
			return this.name;
    }-*/;

    /**
     * Sets the name.
     * 
     * @param name the new name
     */
    public final native void setName(String name) /*-{
			this.name = name;
    }-*/;

    /**
     * Gets the department.
     * 
     * @return the department
     */
    public final native String getDepartment() /*-{
			return this.department;
    }-*/;

    /**
     * Sets the department.
     * 
     * @param department the new department
     */
    public final native void setDepartment(String department) /*-{
			this.department = department;
    }-*/;

    /**
     * Gets the title.
     * 
     * @return the title
     */
    public final native String getTitle() /*-{
			return this.title;
    }-*/;

    /**
     * Sets the title.
     * 
     * @param title the new title
     */
    public final native void setTitle(String title) /*-{
			this.title = title;
    }-*/;

    /**
     * Gets the start date.
     * 
     * @return the start date
     */
    public final native String getStartDate() /*-{
			return this.startDate;
    }-*/;

    /**
     * Sets the start date.
     * 
     * @param startDate the new start date
     */
    public final native void setStartDate(String startDate) /*-{
			this.startDate = startDate;
    }-*/;

    /**
     * Gets the end date.
     * 
     * @return the end date
     */
    public final native String getEndDate() /*-{
			return this.endDate;
    }-*/;

    /**
     * Sets the end date.
     * 
     * @param endDate the new end date
     */
    public final native void setEndDate(String endDate) /*-{
			this.endDate = endDate;
    }-*/;

    /**
     * Gets the location.
     * 
     * @return the location
     */
    public final native String getLocation() /*-{
			return this.location;
    }-*/;

    /**
     * Sets the location.
     * 
     * @param location the new location
     */
    public final native void setLocation(String location) /*-{
			this.location = location;
    }-*/;

    /**
     * Gets the description.
     * 
     * @return the description
     */
    public final native String getDescription() /*-{
			return this.description;
    }-*/;

    /**
     * Sets the description.
     * 
     * @param description the new description
     */
    public final native void setDescription(String description) /*-{
			this.description = description;
    }-*/;

  }

  /**
   * The Class ContactAccount.
   */
  public static class ContactAccount extends JavaScriptObject {

    protected ContactAccount() {
    };

    /**
     * New instance.
     * 
     * @return the contact account
     */
    public static final ContactAccount newInstance() {
      return (ContactAccount) JavaScriptObject.createObject();
    }

    /**
     * Gets the domain.
     * 
     * @return the domain
     */
    public final native String getDomain() /*-{
			return this.domain;
    }-*/;

    /**
     * Sets the domain.
     * 
     * @param domain the new domain
     */
    public final native void setDomain(String domain) /*-{
			this.domain = domain;
    }-*/;

    /**
     * Gets the user name.
     * 
     * @return the user name
     */
    public final native String getUserName() /*-{
			return this.username;
    }-*/;

    /**
     * Sets the user name.
     * 
     * @param username the new user name
     */
    public final native void setUserName(String username) /*-{
			this.username = username;
    }-*/;

    /**
     * Gets the user id.
     * 
     * @return the user id
     */
    public final native String getUserId() /*-{
			return this.userid;
    }-*/;

    /**
     * Gets the user id.
     * 
     * @param userid the userid
     * @return the user id
     */
    public final native void getUserId(String userid) /*-{
			this.userid = userid;
    }-*/;

  }

  /**
   * The Interface Callback.
   */
  public interface Callback {
    void onSuccess();

    void onError(ContactError error);
  }

  /**
   * The Interface ContactFindCallback.
   */
  public interface ContactFindCallback {
    void onSuccess(JsArray<Contact> contacts);

    void onError(ContactError error);
  }

  /**
   * The Enum ContactErrorCode.
   */
  public enum ContactErrorCode {
    UNKNOWN_ERROR, INVALID_ARGUMENT_ERROR, NOT_FOUND_ERROR, TIMEOUT_ERROR, PENDING_OPERATION_ERROR, IO_ERROR, NOT_SUPPORTED_ERROR, PERMISSION_DENIED_ERROR
  }

  /**
   * The Class ContactError.
   */
  public static class ContactError extends JavaScriptObject {

    protected ContactError() {
    };

    /**
     * Gets the code.
     * 
     * @return the code
     */
    public final ContactErrorCode getCode() {
      return ContactErrorCode.values()[getCodeNative()];
    }

    private final native int getCodeNative() /*-{
			return this.code;
    }-*/;
  }

  /**
   * The Class ContactFields.
   */
  public static class ContactFields {

    JsArrayString fields = (JsArrayString) JsArrayString.createArray();

    /**
     * Instantiates a new contact fields.
     * 
     * @param field1 the field1
     * @param fields the fields
     */
    public ContactFields(final String field1, final String... fields) {
      this.fields.push(field1);
      if (fields != null) {
        for (String field : fields) {
          this.fields.push(field);
        }
      }
    };

    /**
     * Gets the fields.
     * 
     * @return the fields
     */
    public JsArrayString getFields() {
      return fields;
    }
  }

  /**
   * The Class ContactFindOptions.
   */
  public static class ContactFindOptions {
    ContactFindOptions self = this;
    JavaScriptObject options = JavaScriptObject.createObject();

    /**
     * Filter.
     * 
     * @param filter the filter
     * @return the contact find options
     */
    public native ContactFindOptions filter(String filter) /*-{
			this.@com.google.gwt.mobile.phonegap.api.Contacts.ContactFindOptions::options.filter = filter;
			return this.@com.google.gwt.mobile.phonegap.api.Contacts.ContactFindOptions::self;
    }-*/;

    /**
     * Multiple.
     * 
     * @param multiple the multiple
     * @return the contact find options
     */
    public native ContactFindOptions multiple(boolean multiple) /*-{
			this.@com.google.gwt.mobile.phonegap.api.Contacts.ContactFindOptions::options.multiple = multiple;
			return this.@com.google.gwt.mobile.phonegap.api.Contacts.ContactFindOptions::self;
    }-*/;

    /**
     * Limit.
     * 
     * @param limit the limit
     * @return the contact find options
     */
    public native ContactFindOptions limit(int limit) /*-{
			this.@com.google.gwt.mobile.phonegap.api.Contacts.ContactFindOptions::options.limit = limit;
			return this.@com.google.gwt.mobile.phonegap.api.Contacts.ContactFindOptions::self;
    }-*/;

    /**
     * Updated since.
     * 
     * @param updatedSince the updated since
     * @return the contact find options
     */
    public ContactFindOptions updatedSince(final Date updatedSince) {
      return updatedSince(updatedSince.toString());
    }

    private native ContactFindOptions updatedSince(String updatedSince) /*-{
			this.@com.google.gwt.mobile.phonegap.api.Contacts.ContactFindOptions::options.updatedSince = filter;
			return this.@com.google.gwt.mobile.phonegap.api.Contacts.ContactFindOptions::self;
    }-*/;

    private JavaScriptObject getOptions() {
      return options;
    }
  }

}
